/*
 * @Author: Thatcher Li
 * @Date: 2020-12-28 17:20:55
 * @LastEditors: Thatcher Li
 * @LastEditTime: 2021-01-04 09:30:52
 * @Descripttion: 指针及其应用
 */

#include <string.h>
#include "array.h"

int main(int argc, char const *argv[])
{
    /*====================指针变量的定义与初始化========================*/
    char a, *p;
    int b, *q;

    p = &a;
    q = &b;

    int *p1 = NULL;
    int *p2 = &b;

    printf("&a = %p, &a = %p, &p = %p\n",&a,p,&p);
    printf("&b = %p, &b = %p, &q = %p\n",&b,q,&q);
    printf("sizeof(p)=%d\n",sizeof(p));// 8 byte, 输出 char 型指针变量占用的字节数
    printf("sizeof(q)=%d\n",sizeof(q));// 8 byte
    printf("sizeof(*p)=%d\n",sizeof(*p));// 1 byte, 输出指针所指基类型占用的字节数
    printf("sizeof(*q)=%d\n",sizeof(*q));// 4 byte

    /*==========================间接寻址运算符======================================*/
    int c = 10, *p3 = &c;
    printf("c = %d\n",*p3);
    *p3 = *p3 + 10;   // 等价于 c = c + 10
    printf("c = %d, *p = %d\n",c,*p3);
    printf("*&c = %d\n", *&c);  // 等价于 printf("*&c = %d\n",c);

    /*====================指针和一维数组========================*/
    int *p4, x[] = {2,2,1,9,0,3,7}, k = 6;
    p4 = x;
    printf("*(x+k)=%d\n", x[p4-x+k]);   // p4 - x 指针相减，得到的是两个指针相差的单元个数

    /*====================字符指针========================*/
    char *str1 = "My name is Tony.";
    char *str2 = "Hello.";
    printf("sizeof(*str1)=%d byte\n",sizeof(*str1));// 1 byte
    printf("sizeof(str1)=%d byte\n",sizeof(str1));// 8 byte
    printf("strlen(str1)=%d\n",strlen(str1));// 16

    char s[] = "Do you understand?";
    char *p5 = s;
    while(*p5 != '\0'){
        putchar(*p5++);
    }
    putchar('\n');
    printf("strlen(s)=%d\n",strlen(s));// 18


    /*====================指针和二维数组========================*/
    int arr[3][4] = {
        {0,1,2,3},
        {4,5,6,7},
        {8,9,10,11}
    };

    int *p6 = arr[0];   // 列指针
    printf("二维数组的内容是：\n");
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 4; j++){
            printf("%d\t",*p6++);
        }
        printf("\n");
        
    }

    int (*p7)[4];   // 定义一个列数为4的行指针变量
    p7 = arr;   // 将行指针 p 赋值为数组首地址
    printf("二维数组的内容是：\n");
    for (int i = 0; i < 3; i++){
        for (int j = 0; j < 4; j++){
            // p7 + i 表示数组 arr 的第 i 行的行地址, 相应的 *(p7+i) 表示第 i 行的列地址, *(p7+i) +j 表示 &arr[i][j]
            // 所以 arr[i][j] 可以表示为 *(*(p7+i)+j)
            printf("%d\t",*(*(p7+i)+j));            }
        printf("\n");
    }

    arr2_point_print(arr[0],3,4);

    /*====================指针的高级应用========================*/
    
    // 1.指针数组
    char *str3[6] = {
        "Think in Java",
        "C programming language",
        "Data Structure",
        "English in use",
        "A Writer\'s Reference"
    };
    printf("sizeof(str3)=%d\n",sizeof(str3));   // 48 byte
    printf("sizeof(char *)=%d\n",sizeof(char *));   // 8 byte
    int len = sizeof(str3)/sizeof(char *);
    for (int i = 0; i < len; i++){
        puts(str3[i]);
    }
    
    return 0;
}

